////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2016-2018 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxcafdstatsprocessor.cpp
/// @brief The class that implements IStatsProcessor for AFD.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "camxhal3module.h"
#include "camxmem.h"
#include "camxstatsdebuginternal.h"
#include "camxtrace.h"
#include "camxtuningdatamanager.h"
#include "camxcafdstatsprocessor.h"

CAMX_NAMESPACE_BEGIN

static const CHAR* pDefaultAlgorithmLibraryName = "com.qti.stats.afd";
#if defined(_LP64)
static const CHAR* pDefaultAlgorithmPath        = "/vendor/lib64/camera/components/";
#else // _LP64
static const CHAR* pDefaultAlgorithmPath        = "/vendor/lib/camera/components/";
#endif // _LP64
static const CHAR* pFunctionName                = "CreateAFDAlgorithm";

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::Create
///
/// @brief  Create the object for CAFDStatsProcessor.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult CAFDStatsProcessor::Create(
    IStatsProcessor** ppAFDStatsProcessor)
{
    CAMX_ENTRYEXIT(CamxLogGroupStats);

    CamxResult          result             = CamxResultSuccess;
    CAFDStatsProcessor* pAFDStatsProcessor = NULL;

    if (NULL != ppAFDStatsProcessor)
    {
        pAFDStatsProcessor = CAMX_NEW CAFDStatsProcessor;

        if (NULL != pAFDStatsProcessor)
        {
            *ppAFDStatsProcessor = pAFDStatsProcessor;
        }
        else
        {
            CAMX_LOG_ERROR(CamxLogGroupStats, "CAFDStatsProcessor create failed");
            result = CamxResultENoMemory;
        }
    }
    else
    {
        CAMX_LOG_ERROR(CamxLogGroupStats, "CAFDStatsProcessor::Create Invalid arguments");
        result = CamxResultEInvalidArg;
    }

    CAMX_ASSERT(CamxResultSuccess == result);

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::CAFDStatsProcessor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CAFDStatsProcessor::CAFDStatsProcessor()
    : m_pCHIAFDAlgorithm(NULL)
    , m_pAFDAlgorithmHandler(NULL)
    , m_pAFDIOHandler(NULL)
{
    CAMX_ENTRYEXIT(CamxLogGroupStats);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::SetAFDAlgorithmHandler
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID CAFDStatsProcessor::SetAFDAlgorithmHandler(
    CAFDAlgorithmHandler* pAlgoHandler)
{
    m_pAFDAlgorithmHandler = pAlgoHandler;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::SetAFDIOHandler
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID CAFDStatsProcessor::SetAFDIOHandler(
    CAFDIOHandler* pAFDIOHandler)
{
    m_pAFDIOHandler = pAFDIOHandler;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::Initialize
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult CAFDStatsProcessor::Initialize(
    const StatsInitializeData* pInitializeData)
{
    CAMX_ENTRYEXIT(CamxLogGroupStats);

    CamxResult  result       = CamxResultSuccess;
    const CHAR* pLibraryName = NULL;
    const CHAR* pLibraryPath = NULL;

    m_pfnCreate              = NULL;
    m_pStaticSettings        = pInitializeData->pHwContext->GetStaticSettings();

    CAMX_ASSERT(NULL != m_pStaticSettings);
    CAMX_ASSERT(pInitializeData != NULL);
    CAMX_ASSERT(pInitializeData->pHwContext != NULL);
    CAMX_ASSERT(pInitializeData->pTuningDataManager != NULL);

    // Create an instance of the core agorithm
    if (NULL == m_pCHIAFDAlgorithm)
    {
        // create and load algorithm
        AFDAlgoCreateParamList createParamList                       = {};
        AFDAlgoCreateParam     createParams[AFDCreateParamTypeCount] = {};

        createParams[AFDAlgoCreateParamsLoggerFunctionPtr].createParamType =
            AFDAlgoCreateParamsLoggerFunctionPtr;
        createParams[AFDAlgoCreateParamsLoggerFunctionPtr].pCreateParam =
            reinterpret_cast<VOID*>(StatsLoggerFunction);
        createParams[AFDAlgoCreateParamsLoggerFunctionPtr].sizeOfCreateParam =
            sizeof(StatsLoggingFunction);

        createParamList.paramCount = AFDCreateParamTypeCount;
        createParamList.pCreateParamList = &createParams[0];

        if (FALSE == m_pStaticSettings->enableCustomAlgoAFD)
        {
            pLibraryName = pDefaultAlgorithmLibraryName;
            pLibraryPath = pDefaultAlgorithmPath;
        }
        else
        {
            pLibraryName = m_pStaticSettings->customAlgoAFDName;
            pLibraryPath = m_pStaticSettings->customAlgoAFDPath;
        }

        // Create an instance of the core algorithm
        VOID* pAddr = StatsUtil::LoadAlgorithmLib(&m_hHandle, pLibraryPath, pLibraryName, pFunctionName);

        CAMX_ASSERT(NULL != pAddr);

        if (NULL == pAddr)
        {
            result = CamxResultEUnableToLoad;

            CAMX_ASSERT_ALWAYS_MESSAGE("Unable to load the algo library: %s/%s", pLibraryPath, pLibraryName);

            if (NULL != m_hHandle)
            {
                OsUtils::LibUnmap(m_hHandle);
            }
        }
        else
        {
            CREATEAFD  pAFD = reinterpret_cast<CREATEAFD>(pAddr);
            result = (*pAFD)(&createParamList, &m_pCHIAFDAlgorithm);
        }
    }

    m_pTuningDataManager = pInitializeData->pTuningDataManager->GetChromatix();
    m_pAFDIOHandler = CAMX_NEW CAFDIOHandler();

    if (NULL == m_pAFDIOHandler)
    {
        CAMX_LOG_ERROR(CamxLogGroupStats, "Auto Flicker Detection IO Handler Allocation failed");
        result = CamxResultENoMemory;
    }

    if (CamxResultSuccess == result)
    {
        result = m_pAFDIOHandler->Initialize(pInitializeData);

    }
    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::ExecuteProcessRequest
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult CAFDStatsProcessor::ExecuteProcessRequest(
    const StatsProcessRequestData* pStatsProcessRequestDataInfo)
{
    CAMX_ENTRYEXIT(CamxLogGroupStats);

    CamxResult         result  = CamxResultSuccess;
    AFDAlgoInputList   input   = { 0 };
    AFDAlgoOutputList* pOutput = NULL;
    UINT64             requestId = pStatsProcessRequestDataInfo->requestId;

    const StaticSettings* pStaticSettings = HwEnvironment::GetInstance()->GetStaticSettings();

    /// Fill RS stats config from algo
    GetRSStatsFromAlgo();

    /// Get an output buffer to hold AFD algorithm output
    pOutput = m_pAFDIOHandler->GetAFDOutputBuffers();
    m_pAFDIOHandler->GetAlgoOutputBuffers(pOutput);

    if (TRUE == pStatsProcessRequestDataInfo->skipProcessing ||
        StatsOperationModeFastConvergence == pStatsProcessRequestDataInfo->operationMode ||
        pStaticSettings->maxPipelineDelay >= pStatsProcessRequestDataInfo->requestId ||
        TRUE == pStaticSettings->disableAFDStatsProcessing)
    {
        CAMX_LOG_VERBOSE(CamxLogGroupStats,
                         "Skip algo processing, RequestId=%llu operationMode:%d "
                         "skipProcessing:%d disableAFDStatsProcessing:%d"
                          "maxPipelineDelay:%d",
                         pStatsProcessRequestDataInfo->requestId,
                         pStatsProcessRequestDataInfo->operationMode,
                         pStatsProcessRequestDataInfo->skipProcessing,
                         pStaticSettings->disableAFDStatsProcessing,
                         pStaticSettings->maxPipelineDelay);
    }
    else
    {
        result = ReadHALAFDParam(&m_HALParam);
        if (CamxResultSuccess != result)
        {
            CAMX_LOG_ERROR(CamxLogGroupStats,
                "RequestId=%llu Failed to ReadHALAFDParam",
                pStatsProcessRequestDataInfo->requestId);
        }
        else
        {
            result = PrepareInputParams(&requestId, &input);
        }
        if (CamxResultSuccess != result)
        {
            CAMX_LOG_ERROR(CamxLogGroupStats,
                "RequestId=%llu Failed to PrepareInputParams",
                pStatsProcessRequestDataInfo->requestId);
        }
        else
        {
            result = ProcessSetParams(pStatsProcessRequestDataInfo->pTuningModeData);
        }
        if (CamxResultSuccess != result)
        {
            CAMX_LOG_ERROR(CamxLogGroupStats,
                "RequestId=%llu Failed to ProcessSetParams",
                pStatsProcessRequestDataInfo->requestId);
        }
        else
        {
            result = m_pCHIAFDAlgorithm->AFDProcess(m_pCHIAFDAlgorithm, &input, pOutput);
        }
        if (CamxResultSuccess != result)
        {
            CAMX_LOG_ERROR(CamxLogGroupStats,
                "RequestId=%llu Failed AFDProcess",
                pStatsProcessRequestDataInfo->requestId);
        }

    }
    m_pAFDIOHandler->PublishOutput(pOutput);

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::GetRSStatsFromAlgo
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID CAFDStatsProcessor::GetRSStatsFromAlgo()
{
    AFDAlgoOutput           outputdata    = { 0 };
    AFDAlgoOutputList       output;
    AFDAlgoGetParam         getParam;

    outputdata.outputType      = AFDAlgoOutputRowSumConfig;
    outputdata.pAFDOutput      = &m_pAFDIOHandler->m_rowSumConfig;
    outputdata.sizeOfAFDOutput = sizeof(m_pAFDIOHandler->m_rowSumConfig);

    output.outputCount             = 1;
    output.pAFDOutputList          = &outputdata;

    // Get initial data
    getParam.type                  = AFDAlgoGetParamStatsConfig;
    getParam.input.pInputData      = NULL;
    getParam.input.sizeOfInputData = 0;
    getParam.output.pOutputData    = outputdata.pAFDOutput;
    getParam.output.sizeOfOutputData = static_cast<UINT32>(output.pAFDOutputList->sizeOfAFDOutput);

    if (NULL != m_pCHIAFDAlgorithm)
    {
        m_pCHIAFDAlgorithm->AFDGetParam(m_pCHIAFDAlgorithm, &getParam);
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::PrepareInputParams()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult CAFDStatsProcessor::PrepareInputParams(
    UINT64*           pRequestId,
    AFDAlgoInputList* pInputList)
{
    CAMX_ENTRYEXIT(CamxLogGroupStats);
    CamxResult result = CamxResultSuccess;

    pInputList->pAFDInputList = m_inputArray;
    pInputList->inputCount    = 0;

    if (NULL == m_pAFDIOHandler)
    {
        CAMX_LOG_ERROR(CamxLogGroupStats, "AFD IO Handler NULL pointer");
        return CamxResultEInvalidPointer;
    }


    StatsBayerGrid* pBGStat   = m_pAFDIOHandler->ReadBGStat();
    if (NULL == pBGStat)
    {
        CAMX_LOG_ERROR(CamxLogGroupStats, "BG Stat NULL pointer");
        return CamxResultEInvalidPointer;
    }
    else
    {
        UpdateInputParam(pInputList, AFDAlgoInputType::AFDAlgoInputBayerGrid,
            sizeof(StatsBayerGrid), static_cast<VOID*>(pBGStat));
    }

    if (NULL == pRequestId)
    {
        CAMX_LOG_ERROR(CamxLogGroupStats, "Request Id NULL pointer");
        return CamxResultEInvalidPointer;
    }
    else
    {
        UpdateInputParam(pInputList, AFDAlgoInputType::AFDAlgoInputFrameID,
            sizeof(UINT64), static_cast<VOID*>(pRequestId));
    }

    StatsRowSum* pRStat    = m_pAFDIOHandler->ReadRowSumStat();
    if (NULL == pRStat)
    {
        CAMX_LOG_ERROR(CamxLogGroupStats, "pRStat NULL pointer");
        return CamxResultEInvalidPointer;
    }
    else
    {
        UpdateInputParam(pInputList, AFDAlgoInputType::AFDAlgoInputRowSum,
            sizeof(StatsRowSum), static_cast<VOID*>(pRStat));
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::UpdateInputParam
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CAMX_INLINE VOID CAFDStatsProcessor::UpdateInputParam(
    AFDAlgoInputList* pInputList,
    AFDAlgoInputType  inputType,
    UINT32            inputSize,
    VOID*             pValue)
{
    CAMX_ENTRYEXIT(CamxLogGroupStats);
    pInputList->pAFDInputList[pInputList->inputCount].inputType      = inputType;
    pInputList->pAFDInputList[pInputList->inputCount].sizeOfAFDInput = static_cast<UINT32>(inputSize);
    pInputList->pAFDInputList[pInputList->inputCount].pAFDInput      = pValue;
    pInputList->inputCount++;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::ProcessSetParams
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult CAFDStatsProcessor::ProcessSetParams(
    ChiTuningModeParameter* pInputTuningModeData)
{
    CAMX_ENTRYEXIT(CamxLogGroupStats);

    CamxResult          result                         = CamxResultSuccess;
    AFDAlgoSetParam     setParam[AFDSetParamLastIndex] = { { 0 } };
    AFDAECInfo*         pAFDAECInfo                    = NULL;
    AFDAFInfo*          pAFDAFInfo                     = NULL;
    AFDSensorInfo*      pAFDSensorInfo                 = NULL;
    AFDAlgoSetParamList setParamList;
    UINT                binningTypeVertical;
    FLOAT               sensorLinesPerSecond;
    UINT32              linesCoveredByRowStats;

    setParamList.numberOfSetParam = 0;
    setParamList.pAFDSetParamList = setParam;

    CAMX_ASSERT_MESSAGE(NULL != m_pAFDIOHandler, "AFD IO Handler NULL pointer");

    pAFDAECInfo                                        = m_pAFDIOHandler->ReadAECInput();
    setParam[AFDAlgoSetParamAECInfo].pAFDSetParam      = static_cast<VOID*>(pAFDAECInfo);
    setParam[AFDAlgoSetParamAECInfo].setParamType      = AFDAlgoSetParamAECInfo;
    setParam[AFDAlgoSetParamAECInfo].sizeOfAFDSetParam = sizeof(AFDAECInfo);
    setParamList.numberOfSetParam                      = setParamList.numberOfSetParam + 1;
    CAMX_LOG_VERBOSE(CamxLogGroupStats, "ET:%f AecSettled:%d LI:%f RG:%f",
        pAFDAECInfo->currentExpTime, pAFDAECInfo->isAECsettled, pAFDAECInfo->luxIDx, pAFDAECInfo->realGain);

    pAFDAFInfo                                        = m_pAFDIOHandler->ReadAFInput();
    setParam[AFDAlgoSetParamAFInfo].pAFDSetParam      = static_cast<VOID*>(pAFDAFInfo);
    setParam[AFDAlgoSetParamAFInfo].setParamType      = AFDAlgoSetParamAFInfo;
    setParam[AFDAlgoSetParamAFInfo].sizeOfAFDSetParam = sizeof(AFDAFInfo);
    setParamList.numberOfSetParam                     = setParamList.numberOfSetParam + 1;
    CAMX_LOG_VERBOSE(CamxLogGroupStats, "AFIsSearching:%d", pAFDAFInfo->isAFSearching);

    pAFDSensorInfo = m_pAFDIOHandler->ReadSensorInput();
    if (pAFDSensorInfo->binningTypeV == 0)
    {
        binningTypeVertical = 1;
    }
    else
    {
        binningTypeVertical = pAFDSensorInfo->binningTypeV;
    }

    /* compute timing settings: compute sensor line time, then multiple by # of lines covered row stats array */
    sensorLinesPerSecond = pAFDSensorInfo->maxFPS * static_cast<FLOAT>(pAFDSensorInfo->numLinesPerFrame);
    if (sensorLinesPerSecond <= 0)
    {
        sensorLinesPerSecond = 1;
    }

    m_pAFDIOHandler->m_rowSumInfo.rowSumCount =
        m_pAFDIOHandler->m_rowSumInfo.horizontalRegionCount * m_pAFDIOHandler->m_rowSumInfo.verticalRegionCount;
    linesCoveredByRowStats = m_pAFDIOHandler->m_rowSumInfo.verticalRegionCount * m_pAFDIOHandler->m_rowSumInfo.regionHeight;

    pAFDSensorInfo->rowSumTime = (linesCoveredByRowStats / sensorLinesPerSecond);
    CAMX_LOG_VERBOSE(CamxLogGroupStats, "sensorLinesPerSecond:%f rowSumCount:%d rowSumTime:%lf linesCoveredByRowStats %u",
        sensorLinesPerSecond,
        m_pAFDIOHandler->m_rowSumInfo.rowSumCount,
        pAFDSensorInfo->rowSumTime,
        linesCoveredByRowStats);

    setParam[AFDAlgoSetParamAFDMode].pAFDSetParam            = static_cast<VOID*>(&m_HALParam.antiBandingMode);
    setParam[AFDAlgoSetParamAFDMode].setParamType            = AFDAlgoSetParamAFDMode;
    setParam[AFDAlgoSetParamAFDMode].sizeOfAFDSetParam       = sizeof(m_HALParam.antiBandingMode);
    setParamList.numberOfSetParam                            = setParamList.numberOfSetParam + 1;

    setParam[AFDAlgoSetParamSensorInfo].pAFDSetParam         = static_cast<VOID*>(pAFDSensorInfo);
    setParam[AFDAlgoSetParamSensorInfo].setParamType         = AFDAlgoSetParamSensorInfo;
    setParam[AFDAlgoSetParamSensorInfo].sizeOfAFDSetParam    = sizeof(AFDSensorInfo);
    setParamList.numberOfSetParam                            = setParamList.numberOfSetParam + 1;

    StatsTuningData statsTuningData = { 0 };
    SetAlgoChromatix(pInputTuningModeData, &statsTuningData);
    setParam[AFDAlgoSetParamChromatixData].pAFDSetParam      = static_cast<VOID*>(&statsTuningData);
    setParam[AFDAlgoSetParamChromatixData].setParamType      = AFDAlgoSetParamChromatixData;
    setParam[AFDAlgoSetParamChromatixData].sizeOfAFDSetParam = sizeof(StatsTuningData);
    setParamList.numberOfSetParam                            = setParamList.numberOfSetParam + 1;

    CDKResult cdkResult = m_pCHIAFDAlgorithm->AFDSetParam(m_pCHIAFDAlgorithm, &setParamList);
    result              = AlgorithmResultToCamXResult(cdkResult);

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::GetDependencies
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult CAFDStatsProcessor::GetDependencies(
    const StatsProcessRequestData* pStatsProcessRequestDataInfo,
    StatsDependency*               pStatsDependency)
{
    CAMX_UNREFERENCED_PARAM(pStatsDependency);
    CAMX_ENTRYEXIT(CamxLogGroupStats);
    CamxResult result = CamxResultSuccess;

    if (TRUE == pStatsProcessRequestDataInfo->skipProcessing)
    {
        // We need to publish previous frame data to property pool when skipProcessing flag is set.
        // Add previous frame(offset = 1) AFD Frame/Stats Control properties as dependency.
        pStatsDependency->properties[0] = { PropertyIDAFDStatsControl, 1,  StatsDependencyGroup::GROUP_NORMAL };
        pStatsDependency->propertyCount = 1;

    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::IsDependenciesSatisfied
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult CAFDStatsProcessor::IsDependenciesSatisfied(
    const StatsProcessRequestData* pStatsProcessRequestDataInfo,
    BOOL*                          pIsSatisfied)
{
    CAMX_ENTRYEXIT(CamxLogGroupStats);

    CamxResult   result           = CamxResultSuccess;
    BOOL         isSatisfiedHDRBE = FALSE;
    BOOL         isSatisfiedRS    = FALSE;
    ISPStatsType statsType;

    for (INT32 i = 0; i < pStatsProcessRequestDataInfo->bufferCount; i++)
    {
        statsType = pStatsProcessRequestDataInfo->bufferInfo[i].statsType;
        switch (statsType)
        {
            case ISPStatsTypeHDRBE:
                isSatisfiedHDRBE = TRUE;
                break;
            case ISPStatsTypeRS:
                isSatisfiedRS = TRUE;
                break;
            default:
                break;
        }
    }

    *pIsSatisfied = (isSatisfiedHDRBE && isSatisfiedRS);

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// CAFDStatsProcessor::~CAFDStatsProcessor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CAFDStatsProcessor::~CAFDStatsProcessor()
{
    CAMX_ENTRYEXIT(CamxLogGroupStats);

    if (NULL != m_pCHIAFDAlgorithm)
    {
        m_pCHIAFDAlgorithm->AFDDestroy(m_pCHIAFDAlgorithm);
        m_pCHIAFDAlgorithm = NULL;
    }

    if (NULL != m_pAFDAlgorithmHandler)
    {
        CAMX_DELETE m_pAFDAlgorithmHandler;
        m_pAFDAlgorithmHandler = NULL;
    }

    if (NULL != m_pAFDIOHandler)
    {
        CAMX_DELETE m_pAFDIOHandler;
        m_pAFDIOHandler = NULL;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CAFDStatsProcessor::ReadHALAFDParam
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult CAFDStatsProcessor::ReadHALAFDParam(
    AFDHALParam* pHALParam
    ) const
{
    CamxResult result       = CamxResultSuccess;
    UINT       HALAFDData[] =
    {
        InputControlAEAntibandingMode,
    };
    static const UINT HALAFDDataLength        = CAMX_ARRAY_SIZE(HALAFDData);
    VOID*  pData[HALAFDDataLength]            = { 0 };
    UINT64 HALAFDDataOffset[HALAFDDataLength] = { 0 };

    m_pAFDIOHandler->m_pNode->GetDataList(HALAFDData, pData, HALAFDDataOffset, HALAFDDataLength);

    Utils::Memcpy(&pHALParam->antiBandingMode, (pData[0]), sizeof(pHALParam->antiBandingMode));
    CAMX_LOG_VERBOSE(CamxLogGroupStats, "antiBandingMode: %d", pHALParam->antiBandingMode);

    m_pAFDIOHandler->SetHALParam(pHALParam);

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CAFDStatsProcessor::SetAlgoChromatix
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult CAFDStatsProcessor::SetAlgoChromatix(
    ChiTuningModeParameter* pInputTuningModeData,
    StatsTuningData*        pTuningData)
{
    CamxResult              result = CamxResultSuccess;

    if (NULL != pInputTuningModeData)
    {
        pTuningData->pTuningSetManager    = m_pTuningDataManager;
        pTuningData->pTuningModeSelectors = reinterpret_cast<TuningMode*>(&pInputTuningModeData->TuningMode[0]);
        pTuningData->numSelectors         = pInputTuningModeData->noOfSelectionParameter;
        CAMX_LOG_VERBOSE(CamxLogGroupStats,
            "Tuning data as mode: %d usecase %d  feature1 %d feature2 %d scene %d, effect %d,",
            pInputTuningModeData->TuningMode[0].mode,
            pInputTuningModeData->TuningMode[2].subMode.usecase,
            pInputTuningModeData->TuningMode[3].subMode.feature1,
            pInputTuningModeData->TuningMode[4].subMode.feature2,
            pInputTuningModeData->TuningMode[5].subMode.scene,
            pInputTuningModeData->TuningMode[6].subMode.effect);
    }
    else
    {
        CAMX_LOG_ERROR(CamxLogGroupStats, "Input tuning data is NULL pointer");
    }

    return result;
}

CAMX_NAMESPACE_END
